import { asType } from '@gnlab/utils'
import { ImportantEditModal } from '@/desktop/components'
import {
  type Word,
  type TextWord,
  type WordTypes,
  WordType,
  wordTitleMap,
  emptyWords,
} from '@/services/common/definition'

import EditAudio from './EditAudio'
import EditFile from './EditFile'
import EditGroupAt from './EditGroupAt'
import EditGroupInvite from './EditGroupInvite'
import EditImages from './EditImages'
import EditLinkCard from './EditLinkCard'
import EditMp from './EditMp'
import EditPersonCard from './EditPersonCard'
import EditText from './EditText'
import EditVideo from './EditVideo'
import EditVideonum from './EditVideonum'

type Editor<T extends Word> = (props: {
  word: T
  onSave: (word: T) => void
  onCancel: () => void
}) => JSX.Element
type Editors = { [type in WordType]: Editor<WordTypes[type]> | [Editor<WordTypes[type]>, number] }
const editorMap: Editors = {
  [WordType.Text]: EditText,
  [WordType.Images]: EditImages,
  [WordType.Video]: EditVideo,
  [WordType.Audio]: EditAudio,
  [WordType.File]: EditFile,
  [WordType.LinkCard]: EditLinkCard,
  [WordType.PersonCard]: [EditPersonCard, 800],
  [WordType.MiniProgram]: [EditMp, 600],
  [WordType.Videonum]: [EditVideonum, 600],
  [WordType.GroupInvite]: [EditGroupInvite, 900],
  [WordType.GroupAt]: EditGroupAt,
}

export function EditWord(props: {
  editing: null | WordType | Word // null: 不编辑  WordType: 新增  Word: 编辑
  customize?: Partial<Record<WordType, Record<string, unknown>>> // 传递给指定类型 editor 的定制 props
  onSave: (word: Word) => void
  onCancel: () => void
}) {
  const { editing, customize, onSave, onCancel } = props

  const word =
    editing !== null
      ? ((typeof editing === 'string' ? { ...emptyWords[editing] } : { ...editing }) as TextWord)
      : null

  const title =
    word !== null
      ? `${typeof editing === 'string' ? '添加' : '编辑'}${wordTitleMap[word.type]}`
      : ''

  const modals = Object.entries(editorMap).map(([modalType, editorPair]) => {
    if (!asType<WordType.Text>(modalType)) return null

    const [Editor, width] = (Array.isArray(editorPair) ? editorPair : [editorPair, null]) as [
      Editor<TextWord>,
      number | null,
    ]

    return <ImportantEditModal
      key={modalType}
      open={word?.type === modalType}
      onCancel={onCancel}
      title={title}
      width={width !== null ? `${width}px` : undefined}
    >
      {word?.type === modalType ? (
        <Editor
          word={word}
          onSave={onSave}
          onCancel={onCancel}
          {...(customize?.[modalType] ?? {})}
        />
      ) : null}
    </ImportantEditModal>
  })

  return <>{modals}</>
}
